---
title: Realtime Transport Layer
description: Learn about the different transport layers that can be used with Realtime Agents.
---

import { Steps } from '@astrojs/starlight/components';
import { Code } from '@astrojs/starlight/components';

import createAgentExample from '../../../../../../examples/docs/voice-agents/createAgent.ts?raw';
import multiAgentsExample from '../../../../../../examples/docs/voice-agents/multiAgents.ts?raw';
import createSessionExample from '../../../../../../examples/docs/voice-agents/createSession.ts?raw';
import configureSessionExample from '../../../../../../examples/docs/voice-agents/configureSession.ts?raw';
import handleAudioExample from '../../../../../../examples/docs/voice-agents/handleAudio.ts?raw';
import defineToolExample from '../../../../../../examples/docs/voice-agents/defineTool.ts?raw';
import toolApprovalEventExample from '../../../../../../examples/docs/voice-agents/toolApprovalEvent.ts?raw';
import guardrailsExample from '../../../../../../examples/docs/voice-agents/guardrails.ts?raw';
import guardrailSettingsExample from '../../../../../../examples/docs/voice-agents/guardrailSettings.ts?raw';
import audioInterruptedExample from '../../../../../../examples/docs/voice-agents/audioInterrupted.ts?raw';
import sessionInterruptExample from '../../../../../../examples/docs/voice-agents/sessionInterrupt.ts?raw';
import sessionHistoryExample from '../../../../../../examples/docs/voice-agents/sessionHistory.ts?raw';
import historyUpdatedExample from '../../../../../../examples/docs/voice-agents/historyUpdated.ts?raw';
import updateHistoryExample from '../../../../../../examples/docs/voice-agents/updateHistory.ts?raw';
import customWebRTCTransportExample from '../../../../../../examples/docs/voice-agents/customWebRTCTransport.ts?raw';
import websocketSessionExample from '../../../../../../examples/docs/voice-agents/websocketSession.ts?raw';
import transportEventsExample from '../../../../../../examples/docs/voice-agents/transportEvents.ts?raw';
import thinClientExample from '../../../../../../examples/docs/voice-agents/thinClient.ts?raw';

## Default transport layers

### Connecting over WebRTC

The default transport layer uses WebRTC. Audio is recorded from the microphone
and played back automatically.

To use your own media stream or audio element, provide an
`OpenAIRealtimeWebRTC` instance when creating the session.

<Code lang="typescript" code={customWebRTCTransportExample} />

### Connecting over WebSocket

Pass `transport: 'websocket'` or an instance of `OpenAIRealtimeWebSocket` when creating the session to use a WebSocket connection instead of WebRTC. This works well for server-side use cases, for example
building a phone agent with Twilio.

<Code lang="typescript" code={websocketSessionExample} />

Use any recording/playback library to handle the raw PCM16 audio bytes.

### Building your own transport mechanism

If you want to use a different speech-to-speech API or have your own custom transport mechanism, you
can create your own by implementing the `RealtimeTransportLayer` interface and emit the `RealtimeTransportEventTypes` events.

## Interacting with the Realtime API more directly

If you want to use the OpenAI Realtime API but have more direct access to the Realtime API, you have
two options:

### Option 1 - Accessing the transport layer

If you still want to benefit from all of the capabilities of the `RealtimeSession` you can access
your transport layer through `session.transport`.

The transport layer will emit every event it receives under the `*` event and you can send raw
events using the `sendEvent()` method.

<Code lang="typescript" code={transportEventsExample} />

### Option 2 — Only using the transport layer

If you don't need automatic tool execution, guardrails, etc. you can also use the transport layer
as a "thin" client that just manages connection and interruptions.

<Code lang="typescript" code={thinClientExample} />
